﻿using System.Runtime.InteropServices;
using System;
using WORD = System.UInt16;
using BYTE = System.Byte;
using System.Diagnostics;
namespace RFIDReader
{
    public class MasterRD
    {
        #region Custom Methods
        /// <summary>
        /// Selects a specific card.
        /// </summary>
        /// <param name="readerID"></param>
        /// <param name="timeout"></param>
        /// <param name="WAK"></param>
        /// <param name="card"></param>
        /// <returns>returns true if the card was found.</returns>
        internal static bool SelectSpecificCard(ushort readerID, int timeout, RequestMode WAK, ushort card)
        {
            MResponse last;
            
            byte[] uid = new byte[16];
            byte len = 0;
            Stopwatch sw = new Stopwatch();
            sw.Reset();
            sw.Start();
            while (sw.ElapsedMilliseconds < timeout)
            {
                ushort atq = 0;
                last = rf_ISO14443A_Request(readerID, WAK, ref atq);
                Console.WriteLine("Request:{0} - ATQ:{1}", last, atq.ToString("X4"));
                if (atq == card)
                {
                    last = rf_ISO14443A_GetCard(readerID, WAK, uid, ref len);
                    var ussen = System.BitConverter.ToString(uid, 0, len);
                    Console.WriteLine("GetCard:{0} - uid:{1}, Len:{2}", last, ussen, len);
                    return true;
                }
            }
            sw.Stop();
            return false;
        }
        internal static MResponse SelectDesfireSelectApplication(ushort readerID, byte[] app)
        {
            Console.WriteLine("SelectDesfireSelectApplication()+");
            byte[] pData = new byte[16];
            byte plen = 0;
            MResponse last = rf_ISO14443_4_TypeA_RATS(readerID, pData, ref plen);
            Console.WriteLine("RATS:{2}\tResponse:{0} Length:{1}", BitConverter.ToString(pData, 0, plen), plen, last);

            byte[] SelectApplications = new byte[4] { 0x5A, app[2], app[1], app[0] };
            last = rf_ISO14443_4_COS(readerID, SelectApplications, 4, pData, ref plen, 2000);
            Console.WriteLine("PIC:{2}\tResponse:{0} Length:{1}", BitConverter.ToString(pData, 0, plen), plen, last);
            Console.WriteLine("SelectDesfireSelectApplication({0})-", last);
            return last;
        }
        internal static MResponse GetDesfireApplications(ushort readerID)
        {
            Console.WriteLine("GetDesfireApplications()+");
            byte[] pData = new byte[58];
            byte plen = 0;
            byte[] GetApplicationIDs = { 0x6A };
            MResponse last = rf_ISO14443_4_COS(readerID, GetApplicationIDs, 1, pData, ref plen, 2000);
            Console.WriteLine("GetAppID:\tResponse:{0} Length:{1}", BitConverter.ToString(pData, 0, plen), plen);
            Console.WriteLine("GetDesfireApplications({0})-", last);
            return last;
        }
        #endregion

        #region COM
        /// <summary>
        /// Closes the com port
        /// </summary>
        /// <param name="port">comport to close</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_COM_Close(UInt32 port);
        
        /// <summary>
        /// Opens Comport
        /// </summary>
        /// <param name="comport">number of Comport to open</param>
        /// <param name="baud">Baud Rate</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_COM_Open(UInt32 comport, Int32 baud);
        #endregion

        #region ISO14443A

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_ISO14443_4_COS(UInt16 nReaderID, Byte[] pcApduIn, Byte cApduLen, Byte[] pcResultOut, ref Byte pcResultLen, Int32 dwTimeOut);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_ISO14443A_GetCard(UInt16 readerID, RequestMode mode, Byte[] data, ref Byte length);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_ISO14443A_Halt(UInt16 ReaderID);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_ISO14443_4_TypeA_RATS(UInt16 nReaderID, Byte[] pcATS, ref Byte pcLen);

        /// <summary>
        /// ISO14443 request card
        /// </summary>
        /// <param name="reader">reader ID</param>
        /// <param name="mode">request Mode; 0x26: REQA; 0x52: WUPA</param>
        /// <param name="ATQ">pointer to ATQA, 2 bytes, returned from card</param>
        /// <remarks>If REQA mode is used with rf_ISO14443A_GetCard then Halt this will not return success. Must use WUPA mode.</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_ISO14443A_Request(UInt16 reader, RequestMode mode, ref UInt16 ATQ);
        #endregion

        #region Reader
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_ComOpen(UInt32 comport, UInt16 readerID);
        
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_Close(UInt16 reader);
        
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_SetBeep(UInt16 reader, Byte time);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_AntennaON(UInt16 reader);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_AntennaOFF(UInt16 reader);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_SetISOType(UInt16 p, Byte p_2);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_GetVer(UInt32[] pnVer);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_SetID(UInt16 nReaderID, UInt16 nNewReaderID);

        [DllImport("MasterRD.dll", EntryPoint = "rf_Reader_GetID", CharSet = CharSet.Auto)]
        public extern static MResponse rf_Reader_GetID(ref UInt16 pnReaderID);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_GetFirmwareVer(UInt16 nReaderID, ref UInt16 pnVersion);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_GetSN(UInt16 nReaderID, Byte[] pcSNR);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_Reader_SetLed(UInt16 nReaderID, Byte cLedID, Byte cTimes, Byte cPeriod);

        [DllImport("MasterRD.dll")]
        public static extern MResponse rf_USSEN_SetMem(UInt16 nReaderID, Byte[] pcDataIn, UInt32 cDataLen);

        [DllImport("MasterRD.dll")]
        public static extern MResponse rf_USSEN_GetMem(UInt16 nReaderID, Byte[] pcDataOut, ref Byte cDataLen);
        #endregion

        #region SAM
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_SAM_COS(UInt16 reader, Byte samNo, Byte[] apdu, Byte apduLength, Byte[] result, ref Byte resultLength, UInt32 timeout);
        #endregion

        #region UltraLightC
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_UltraLightC_Authentication(UInt16 reader, Byte[] apdu);
        /// <summary>
        /// ultra light card read data(4 pages, 16 bytes)
        /// </summary>
        /// <param name="readerID">Reader ID</param>
        /// <param name="page">start block number of ultra light</param>
        /// <param name="destination">pointer to output data</param>
        /// <remarks>if start block number is 0x0F, then read 4 blocks: 0x0F, 0x00, 0x01 and 0x02</remarks>
        /// <returns>LIB_SUCCESS if successful</returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_UltraLight_Read(UInt16 readerID, Byte page, Byte[] destination);

        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_UltraLight_Write(UInt16 readerID, Byte block, Byte[] writeBuffer);
        #endregion

        #region DES
        [DllImport("MasterRD.dll")]
        public extern static MResponse des_encrypt(Byte[] szOut, Byte[] szIn , UInt32 inlen, Byte[] key, UInt32 keylen);

        [DllImport("MasterRD.dll")]
        public extern static MResponse des_decrypt(Byte[] szOut, Byte[] szIn , UInt32 inlen, Byte[] key, UInt32 keylen);
        #endregion

        #region Mifare 1k/4k
        /// <summary>
        /// Mifare 1K/4K (S50/S70) authentication by specified key
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cMode">0x60: authenticate key A; 0x61: authenticat key B</param>
        /// <param name="cBlock">absolute block number to authenticate; 0x00 - 0x3F for Mifare S50; 0x00 - 0xFF for Mifare S70</param>
        /// <param name="pcKey">pointer to specified key</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_Authentication(UInt16 nReaderID, Byte cMode, Byte cBlock, ref Byte pcKey);

        /// <summary>
        /// download M1 card key to reader
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cKeyIndex">key index to download</param>
        /// <param name="pcKey">pointer to the key to download</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_DownloadKeyToReader(UInt16 nReaderID, BYTE cKeyIndex, ref BYTE pcKey);

        /// <summary>
        /// M1 authentication by downloaded key
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cMode">authentication mode; 0x60: authenticate key A; 0x61: authenticat key B</param>
        /// <param name="cBlock">absolute block number to authenticate; 0x00 - 0x3F for Mifare S50; 0x00 - 0xFF for Mifare S70</param>
        /// <param name="cKeyIndex">the index of the key</param>
        /// <remarks>need use rf_M1_DownloadKeyToReader to download key first</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_AuthenticateByDownloadedKey(UInt16 nReaderID, BYTE cMode, BYTE cBlock, BYTE cKeyIndex);

        /// <summary>
        /// M1 read data from a block (16 bytes)
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to read; 0x00 - 0x3F for Mifare S50; 0x00 - 0xFF for Mifare S70</param>
        /// <param name="pData">pointer to output data, the length is 16 bytes</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_Read(UInt16 nReaderID, BYTE cBlock, BYTE[] pData/*, BYTE* pLen*/);

        /// <summary>
        /// M1 write data to a block (16 bytes)
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to write; 0x00 - 0x3F for Mifare S50; 0x00 - 0xFF for Mifare S70</param>
        /// <param name="pData">pointer to input data, the length is 16 bytes</param>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_Write(UInt16 nReaderID, BYTE cBlock, BYTE[] pData/*, BYTE len*/);

        /// <summary>
        /// create purse
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to creat purse</param>
        /// <param name="iValue"></param>
        /// <remarks>the sector trailer can't be purse</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseCreate(UInt16 nReaderID, BYTE cBlock, Int32 iValue);

        /// <summary>
        /// read purse remain value
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to read purse</param>
        /// <param name="piValue">pointer to value output</param>
        /// <remarks>the sector trailer can't be purse</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseRead(UInt16 nReaderID, BYTE cBlock, ref Int32 piValue);

        /// <summary>
        /// purse decrement
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to decrement</param>
        /// <param name="iValue">the decrement value</param>
        /// <remarks>the sector trailer can't be purse</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseDecrement(UInt16 nReaderID, BYTE cBlock, Int32 iValue);

        /// <summary>
        /// purse increment
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number to increment</param>
        /// <param name="iValue">the increment value</param>
        /// <remarks>the sector trailer can't be purse</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseIncrement(UInt16 nReaderID, BYTE cBlock, Int32 iValue);

        /// <summary>
        /// backup(copy) a purse from block to another block in same sector
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cSrcBlock">source block, absolute block number</param>
        /// <param name="cDestBlock">destination block, absolute block number</param>
        /// <remarks>the sector trailer can't be purse, the source and target block MUST in same sector</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseBackup(WORD nReaderID, BYTE cSrcBlock, BYTE cDestBlock);

        /// <summary>
        /// data restore from a block to card buffer
        /// </summary>
        /// <param name="nReaderID"> reader ID</param>
        /// <param name="cBlock">absolute block number</param>
        /// <remarks>uses before rf_M1_Transfer</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseRestore(WORD nReaderID, BYTE cBlock);

        /// <summary>
        /// transfer the data in card buffer to a block(eeprom)
        /// </summary>
        /// <param name="nReaderID">reader ID</param>
        /// <param name="cBlock">absolute block number</param>
        /// <remarks>use after rf_M1_Restore</remarks>
        /// <returns></returns>
        [DllImport("MasterRD.dll")]
        public extern static MResponse rf_M1_PurseTransfer(WORD nReaderID, BYTE cBlock);

        #endregion
    }

    public enum MResponse
    {
        LIB_SUCCESS      =  0, //0x00
        LIB_PARAM_ERR    = -1, //0xFF
        LIB_OS_ERR       = -2, //0xFE
        LIB_NETWORK_ERR  = -3, //0xFD
        LIB_TIMEOUT      = -4, //0xFC
        LIB_FAILED       = -5, //0xFB
        LIB_BUS_EXIST    = -6, //0xFA
        LIB_READER_EXIST = -7, //0xF9
    }

    public enum RequestMode : byte
    {
        REQ_STD = 0x26,
        REQ_ALL = 0x52,
    }
}
/*

//return successful result
#define  LIB_SUCCESS      0  
//return failed result
#define  LIB_FAILED       1

#define  MAX_RF_BUFFER    1024

/******** FUNCTION£ºGet Dll Version  2Byte *******************
// PARAMETERS: nothing
//  RETURNED : success - 0
/*********************************************************
int WINAPI lib_ver(unsigned int *Ver);

/******** FUNCTION£ºDES Encrypt  *************************
//  PARAMETERS: szOut - DES resulted data
//               szIn -   encrypted data
//              inlen -    encrypted data length 
//                key -    key
//             keylen:    key length
//    RETURNED : SUCCESS -0
/*********************************************************
int WINAPI des_encrypt(unsigned char *szOut,unsigned char *szIn , unsigned int inlen,unsigned char *key,unsigned int keylen);

/******** FUNCTION£º  DES Decrypt *************************
//  PARAMETERS£ºszOut:  DECRYPT resulted data
//        szIn:   decrypt data
//        inlen:  decypt data length
//        key:    key
//        keylen: key length
//  RETURNED:  SUCCESS - 0
/*********************************************************

int WINAPI des_decrypt(unsigned char *szOut,unsigned char *szIn , unsigned int inlen,unsigned char *key,unsigned int keylen);

/********* FUNCTION£ºinialize port ****************
//PARAMETERS£ºport- port £¬value 0¡«3
//baud£º4800¡«115200
//RETURNED : SUCCESS - 0
/*******************************************
int WINAPI rf_init_com(int port,long baud);

/******** FUNCTION£ºInialize device number *******************************
//  PARAMETERS£ºicdev - device number 0-65536
//RETURNED : SUCCESS - 0
/********************************************************
int WINAPI rf_init_device_number(WORD icdev);

/******** FUNCTION : Get device address****************************
//  PARAMETERS£ºicdev- device number£¬0-65536
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_get_device_number(WORD *Icdev);

/******** FUNCTION£ºGet hardware version , 2 bytes **********
//  PARAMETERS£ºicdev -   device address
//        Version - version information
//  RETURNED : SUCCESS - 0
/********************************************************
int WINAPI rf_get_model(WORD icdev,unsigned short *Version);

/******** FUNCTION£ºGet serial number of hardware,8 bytes **********
//  PARAMETERS£ºicdev - device address
//        Snr£º  return serial number
//  RETURNED  : SUCCESS - 0
/********************************************************
int WINAPI rf_get_snr(WORD icdev,unsigned char *Snr/*,int* pLength);

/******** FUNCTION£ºbeep ************************************
//  PARAMETERS£ºicdev - device address
//        msec£º beep time , unit : 10 ms
//  RETURNED : SUCCESS - 0 
/********************************************************
int	WINAPI rf_beep(WORD icdev,unsigned char msec);

/******** FUNCTION£ºSET  sam card baud rate************
//  PARAMETERS£ºicdev - device address
//        bound: sam card boud rate , value : 9600¡¢38400
//  RETURNED£ºSUCCESS - 0
//  MEMO£ºbound=0:9600
//        bound=1:38400
/********************************************************
int WINAPI rf_init_sam(WORD icdev,unsigned char bound);

/******* FUNCTION£ºreset sam card *******************************
//  PARAMETERS£ºicdev  - device address
//        pData -  return reset information
//        pMsgLg -reset data length
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_sam_rst(WORD icdev, unsigned char *pData,unsigned char* pMsgLg);

/*for example£º
     unsigned int icdev;
     unsigned char pData[MAX_RF_BUFFER];
     unsigned char len;
     status = rf_sam_rst(icdev,pData,&len);
     



/******** FUNCTION£ºsend COS command to SAM card ********************
//  PARAMETERS£ºicdev -  device address
//        command - cos command
//        cmdLen -  cos length
//        pDat -  return data from card , include SW1¡¢SW2
//        pMsgLg -  return data length
//  RETURNED£ºSUCCESS - 0
/********************************************************

int WINAPI rf_sam_cos(WORD icdev, unsigned char *command,unsigned char cmdLen ,unsigned char *pData,unsigned char* Length);

/*for example£º
     unsigned char icdev;
     unsigned char* cmd;
     unsigned char pData[MAX_RF_BUFFER];
     unsigned char len;
     status = rf_sam_cos(icdev,cmd,sizeof(cmd),pData,&len);
     



/*******  FUNCTION£ºset hardware as no-contact mode ************ 
//              ISO14443 TYPE A OR ISO14443 TYPE B
//  PARAMETERS£ºicdev - device address
//        type:  work mode of hardware
//  RETURNED£ºSUCCESS - 0
//  Note£ºtype='A':set TYPE_A mode
//        type='B':set TYPE_B mode
//        type='r':set AT88RF020 mode 
//        type='1':set 15693 mode
/********************************************************

int WINAPI rf_init_type(WORD icdev,unsigned char type);

/*******  FUNCTION£ºcloase or open antenna**************
//  PARAMETERS£ºicdev - device address
//        model - antenna mode
//  RETURNED£ºSUCCESS - 0
//  Note£ºmodel=0 - close antenna
//        model=1 - open antenna
/********************************************************
int WINAPI rf_antenna_sta(WORD icdev, unsigned char mode);

/******** FUNCTION£ºsearch ISO14443-3 TYPE_A card ******************
//  PARAMETERS£ºicdev  - device address
//        model - search card mode 
//  RETURNED£ºSUCCESS - 0
//  Note£ºmode=0x26 -  search card into sleep state 
//        mode=0x52  - search all card 
/********************************************************
int WINAPI rf_request(WORD icdev, unsigned char mode , unsigned short *TagType);

/********* FUNCTION£ºISO14443-3 TYPE_A card defend collide *************
//  PARAMETERS£ºicdev - device address
//        bcnt£º   serial number bytes of card ,value :4¡¢7¡¢10£¬Mifare = 4
//        pSnr£º   return serial number
//        pRLength:return length of pSnr
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_anticoll(WORD icdev, unsigned char bcnt, unsigned char *pSnr,unsigned char* pRLength);

/*for example £ºint status
      unsigned char icdev;
      unsigned char snr[MAX_RF_BUFFER];
      unsigned char len;
      status = rf_anticoll(icdev,4,snr,&len);      



/******** FUNCTION£ºLocked ISO14443-3 TYPE_A card ************
//  PARAMETERS£ºicdev- device address
//        pSnr£º serial number of card
//        srcLen:length of pSnr£¬MifareOne 's value = 4
//        Size£º return card's size
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_select(WORD icdev,unsigned char *pSnr,unsigned char srcLen,unsigned char *Size);

/******* FUNCTION£ºlet invalidated ISO14443-3 TYPE_A card to sleep state 
//  PARAMETERS£ºicdev - device address
//  RETURNED£ºSUCCESS - 0
/*********************************************************
int WINAPI rf_halt(WORD);

/****** FUNCTION£ºdownload Mifare One key from hardware*****************
//one key = every 6 bytes£¬0¡«15 block arrange
//PARAMETERS£ºicdev - device address
//Mode - key type ,value = ¡®A¡¯OR ¡®B¡¯
//key - key£¬96 bytes
//RETURNED£ºSUCCESS -0
/**************************************************************
int WINAPI rf_download_key(WORD icdev, unsigned char mode, unsigned char *key/*,unsigned char* pKeyLen);

/***** FUNCTION£ºauthenticate Mifare One card****************
//  PARAMETERS£ºicdev- device address
//        model£ºkey authentication mode
//        block£ºabsolute block number that need authenticate
//        key£º  key content£¬6 byte
//  RETURNED£ºSUCCESS -0
//  Note£ºmodel=0x60:authenticate A key
//        model=0x61:authenticate B key
/*********************************************************
int WINAPI rf_M1_authentication1(WORD icdev, unsigned char mode, unsigned char secnr);

/*******  FUNCTION£ºread data from one block address of Mifare One***************
//  PARAMETERS£ºicdev£ºdevice address
//        block£º M1 card absolute block address
//        pData£º returned data
//        pLen:   length of data
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_authentication2(WORD icdev,unsigned char mode,unsigned char secnr,unsigned char *key/*,unsigned char KeyLen/);

/*For example£ºint status
      unsigned short icdev
      unsigned char pData[MAX_RF_BUFFER];
      unsigned char len;
      status = rf_M1_read(icdev,0,pData,&len);
      



/*******  FUNCTION£ºread one block data at Mifare one***********
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 card absolute block address
//        data£º read data£¬16 byte
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_read(WORD icdev, unsigned char adr, unsigned char *pData,unsigned char* pLen);

/*for example£ºint status
      unsigned short icdev
      unsigned char pData[MAX_RF_BUFFER];
      unsigned char len;
      status = rf_M1_read(icdev,0,pData,&len);
      



/*******  FUNCTION£ºwrite one block data at Mifare one ***********
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 absolute block address
//        data£º write data£¬16 byte
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_write(WORD icdev, unsigned char adr, unsigned char *data/*,unsigned char len);


/*******  FUNCTION£ºinialize one block of Mifare one as purse ******
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 block address
//        value£ºinialize value
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_initval(WORD icdev, unsigned char adr, long value);

/*******  FUNCTION£ºread Mifare One purse value *********************
//  PARAMETERS£ºicdev£º device address
//        block£º M1 block address
//        pValue£ºreturn value
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_readval(WORD icdev, unsigned char adr,long* pValue);


/*******  FUNCTION£ºMifare One decrement fund *************************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 block address
//        value£ºdecrement value
//  RETURNED£ºSUCCESS - 0
//  Note£ºif run successfully£¬returned data will be saved as buffer of card,
//        and donot modify context of block. if we need save result to card , we need
//        run rf_M1_restore
/********************************************************
int WINAPI rf_M1_decrement(WORD icdev, unsigned char adr,long value);

/******** FUNCTION£ºMifare One increment value *************************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 block address
//        value£ºincrement value
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_M1_increment(WORD icdev, unsigned char adr,long value);

/******** FUNCTION£ºSave as Mifare One value to other block *********************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 block address
//  RETURNED£ºSUCCESS - 0
//  Note£ºIt transfer block context to buffer of card £¬and use
//        rf_M1transfer() to transfer buffer of card to other block
/********************************************************
int WINAPI rf_M1_restore(WORD icdev, unsigned char adr);

/****** FUNCTION£ºtransfer Mifare One value **********************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºM1 block address
//  RETURNED£ºSUCCESS - 0
//  Note£ºit only is called after calling increment¡¢decrement and restore 
/********************************************************
int WINAPI rf_M1_transfer(WORD icdev, unsigned char adr);

/****** FUNCTION£ºRequest ISO14443 TYPE-A card and reset *********************
//  PARAMETERS£ºicdev£ºdevice address
//              model: request model, 0x26, request IDLE, 0x52, request all(WUPA)
//              pData£ºoutput data, 4 bytes snr + reset info.
//              pMsgLg: output data length
//  RETURNED£ºSUCCESS - 0
/********************************************************
int WINAPI rf_typea_rst(WORD icdev,unsigned char model,unsigned char *pData,unsigned char* pMsgLg);

/******** FUNCTION£ºsend cos command to ISO14443-A card  *******
//PARAMETERS£ºicdev£ºdevice address
//command£ºcos command
//MsgLg£ºlength of returned data
//Date£ºreturned data £¬include SW1¡¢SW2
//RETURNED£ºSUCCESS - 0
/****************************************************************
/*for example£ºint status
unsigned short icdev
unsigned char* cmd;
unsigned char pData[MAX_RF_BUFFER];
unsigned char len;

status = rf_cos_command(icdev,cmd,sizeof(cmd),pData,&len);

int WINAPI rf_cos_command(WORD icdev, unsigned char *command,unsigned char cmdLen,unsigned char *pData,unsigned char* pMsgLg);

/******** FUNCTION£ºsearch ISO14443-B card ***********************
//PARAMETERS£ºicdev£ºdevice address
//AFI£º use AFI, if AFI = 0, all cards respond in induce area
//slotmax: max channels number between hardware and rf card
//MsgLg£ºlength of returned data
//Date£ºreturned data
//RETURNED£ºSUCCESS - 0
/****************************************************************
/*for example£ºint status
int icdev
unsigned char msglg
unsigned char pDate[MAX_RF_BUFFER];
status = rf_atqb(icdev,0,1,pDate,&msglg);


int WINAPI rf_atqb(WORD icdev,unsigned char model,unsigned char *pData,unsigned char *pMsgLg);

/*********  FUNCTION£ºactivate all cards of searched ISO14443-B cards ***********
//PARAMETERS£ºicdev£ºdevice address
//PUPI£º flag of card
//CID£º logic address , value 0¡«14 and less than slotmax 
//RETURNED£ºSUCCESS - 0
/****************************************************************
int WINAPI rf_attrib(WORD icdev, unsigned long PUPI, unsigned char CID);

/*********  FUNCTION£ºsend cos command to ISO14443-B card ***
//PARAMETERS£ºicdev£ºdevice address
//CID£º logic address
//command£ºcos command
//MsgLg£ºlength of returned data
//Date£º data of returned data ,include SW1¡¢SW2
//RETURNED£ºSUCCESS - 0
/**************************************************************
/*
for example£ºint status
int icdev
unsigned char *command;
unsigned char msglg;
unsigned char pData[MAX_RF_BUFFER];
status = rf_typeb_cos(icdev,0,command,sizeof(command),pData,&msglg);


int WINAPI rf_typeb_cos(WORD icdev, unsigned char CID,unsigned char *command, unsigned char cmdLen,unsigned char *pData,unsigned char *pMsgLg);

/*********** FUNCTION£ºvalidate AT88RF020 password ***********************
//PARAMETERS£ºicdev£ºdevice address
//key£º password, 8 bytes
//RETURNED£ºSUCCESS - 0
/**************************************************************
int WINAPI rf_at020_check(WORD icdev, unsigned char *key);

//********** FUNCTION£ºread one page data of AT88RF020 card *********************
//PARAMETERS£ºicdev£ºdevice address
//adr£ºpage address£¬£¨0¡«31£©
//Date£ºreturned data£¬8 bytes
//RETURNED£ºSUCCESS - 0
/**************************************************************
/*
for example£ºint status
int icdev
unsigned char pData[MAX_RF_BUFFER];
unsigned char len;
status = rf_at020_read(icdev,0,pData,&len);


int WINAPI rf_at020_read(WORD icdev, unsigned char adr, unsigned char *pData,unsigned char* pMsgLen); 

/*********** FUNCTION£ºwrite  page address data of AT88RF020 *********************
//PARAMETERS£ºicdev£ºdevice address
//adr£ºpage address£¬£¨0¡«31£©
//Date£ºdata £¬8 bytes
//RETURNED£ºSUCCESS - 0
/**************************************************************
int WINAPI rf_at020_write(WORD icdev, unsigned char adr, unsigned char *data/*,unsigned char len/); 

/************** FUNCTION£º*****************************************
//PARAMETERS£ºicdev£ºdevice address
//date£º data£¬4 bytes
//RETURNED£ºSUCCESS - 0
/**************************************************************
int WINAPI rf_at020_lock(WORD icdev,unsigned char *data/*,unsigned char len/);

/********** FUNCTION£º *****************
//PARAMETERS£ºicdev£ºdevice address
//date£º data, 6 bytes
//RETURNED£ºSUCCESS - 0
/***********************************
int WINAPI rf_at020_count(WORD icdev,unsigned char *data/*,unsigned char len/);

/********** FUNCTION£ºlet AT88RF020 to enter HALT state ***************
//PARAMETERS£ºicdev£ºdevice address
//RETURNED£ºSUCCESS - 0
/**************************************************************
int WINAPI rf_at020_deselect(WORD icdev);

/********** FUNCTION£ºset light's color ***************
//PARAMETERS£ºicdev£ºdevice address
//      color: 0 ,black out
//			   1 ,red
//			   2 ,green
//			   3 ,yellow
//RETURNED£ºSUCCESS - 0
/**********************************************

int (WINAPI rf_light)(WORD icdev,unsigned char color);

/********** FUNCTION£º ***************

//RETURNED£ºSUCCESS - 0
/**********************************************
int WINAPI rf_cl_deselect(WORD icdev);

/********** FUNCTION£ºclose port *********************************
int WINAPI rf_ClosePort();

//FUNCTION£ºlock ST card *****************************
//  PARAMETERS£ºicdev£º device address
//        Chip_ID£ºID number
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_st_select(unsigned short icdev, unsigned char* pChip_ID);


/******** FUNCTION£ºlet ST card to enter DESACTIVED state ************
//  PARAMETERS£ºicdev£º  device address
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_st_completion(unsigned short icdev);


/*******  FUNCTION£ºread one block data of SR176 **********************
//  PARAMETERS£ºicdev£º device address
//        block£º block address
//        pData£º returned data
//        pLen:   length of pData
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_sr176_readblock(unsigned short icdev, unsigned char block, unsigned char *pData,unsigned char *pLen);



/*******  FUNCTION£ºwrite one block data of SR176 **********************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºblock address
//        data£º data £¬2 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_sr176_writeblock(unsigned short icdev, unsigned char block, unsigned char *data);



/*******  FUNCTION£ºlock SR176 block *************************
//  PARAMETERS£ºicdev£º device address
//        lockreg:LOCKREG
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_sr176_protectblock(unsigned short icdev, unsigned char lockreg);



/*******  FUNCTION£ºread one block data of SRIX4K *********************
//  PARAMETERS£ºicdev£º device address
//        block£º block address
//        pData:  returned data
//        pLen:	  length of pData
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_srix4k_readblock(unsigned short icdev, unsigned char block, unsigned char *pData,unsigned char *pLen);



/*******  FUNCTION£ºwrite one block dat of SRIX4K *********************
//  PARAMETERS£ºicdev£ºdevice address
//        block£ºblock address
//        pData: data, 4 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_srix4k_writeblock(unsigned short icdev, unsigned char block, unsigned char *pData);



/******** FUNCTION£ºauthenticate SRIX4K **********************
//  PARAMETERS£ºicdev£ºdevice address
//        pData: RND£¬6 bytes
//        pSIG:	 SIG
//        pLen:	 length of SIG
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_srix4k_authenticate(unsigned short icdev, unsigned char *pRND, unsigned char *pSIG, unsigned char *pLen);



/******** FUNCTION£ºget UID of SRIX4K ***********************
//  PARAMETERS£ºicdev£ºdevice address
//        pUID:	 UID
//        pLen:	 length of UID
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_srix4k_getuid(unsigned short icdev, unsigned char *Puid, unsigned char *pLen);

//FUNCTION£ºlock SRIX4K *************************
//  PARAMETERS£ºicdev£ºdevice address
// lockreg:	LOCKREG
/*******************************************************

int WINAPI rf_srix4k_writelockreg(unsigned short icdev, unsigned char lockreg);
/****** FUNCTION£ºlock ultra light *******************
//  PARAMETERS£ºicdev£ºdevice address
//        pSnr£º serial number
          //pLene£ºlength of pSnr
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_ul_select(unsigned short icdev, unsigned char *pSnr,unsigned char *pLen);



/******** FUNCTION£ºwrite one block data of ultra light *********
//  PARAMETERS£ºicdev£º device address
//        page£º  page address of ultra light£¨0¡«0x0f£©
//        data£º  data £¬4bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI rf_ul_write(unsigned short icdev, unsigned char page, unsigned char *data);



/******** FUNCTION£ºISO15693_Inventory ********************
//  PARAMETERS£ºicdev£ºdevice address
//        Pdata: return data£¬DSFID(1 byte)+ UID(8 bytes)
//        pLen:	 Pdata's length
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Inventory(unsigned short icdev, unsigned char *pData, unsigned char *pLen);


/******** FUNCTION£ºISO15693_Stay_Quiet *******************
//  PARAMETERS£ºicdev£ºdevice address
//        UID:	 UID 8 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Stay_Quiet(unsigned short icdev, unsigned char *UID);


/******** FUNCTION£ºISO15693_Select ***********************
//  PARAMETERS£ºicdev£ºdevice address
//        UID:	 UID 8 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Select(unsigned short icdev, unsigned char *UID);


/******** FUNCTION£ºISO15693_Reset_To_Ready ***************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Reset_To_Ready(unsigned short icdev, unsigned char model, unsigned char *UID);


/******** FUNCTION£ºISO15693_Read ************************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        block: block number
//        number: read block numbers£¬< 0x10
//        Pdata: return data
//        pLen:  Pdata's length
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Read(unsigned short icdev, 
                 unsigned char  model,
                             unsigned char  *UID,
                             unsigned char  block,
                             unsigned char  number,
                             unsigned char  *Pdata,
                             unsigned char  *pLen);


/******** FUNCTION£ºISO15693_Write ************************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        block: block number
//        data:  writed data£¬4 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Write(unsigned short icdev, 
                  unsigned char  model,
                  unsigned char  *UID,
                  unsigned char  block, 
                  unsigned char *data);
                  
             
/******** FUNCTION£ºISO15693_Lock_Block *******************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        block: block number
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Lock_Block(unsigned short icdev, unsigned char model, unsigned char *UID, unsigned char block);


/******** FUNCTION£ºISO15693_Write_AFI ********************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        AFI:   writed AFI
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Write_AFI(unsigned short icdev, unsigned char model, unsigned char *UID, unsigned char AFI);


/******** FUNCTION£ºISO15693_Lock_AFI *********************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Lock_AFI(unsigned short icdev, unsigned char model, unsigned char *UID);


/******** FUNCTION£ºISO15693_Write_DSFID ******************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        DSFID: writed DSFID
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Write_DSFID(unsigned short icdev, unsigned char model, unsigned char *UID, unsigned char DSFID);


/******** FUNCTION£ºISO15693_Lock_DSFID *******************
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Lock_DSFID(unsigned short icdev, unsigned char model, unsigned char *UID);


/******** FUNCTION£ºISO15693_Get_System_Information *******
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        Pdata: return data
//        pLen:  Pdata's length
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Get_System_Information(unsigned short icdev, 
                           unsigned char  model,
                           unsigned char  *UID,
                           unsigned char  *Pdata, 
                           unsigned char  *pLen);
                           

/******** FUNCTION£ºISO15693_Get_Block_Security ***********
//  PARAMETERS£ºicdev£ºdevice address
//        model: bit0=Select_flags,bit1=Addres_flags
//        UID:	 UID 8 bytes
//        block: block number
//        number:read block numbers£¬< 0x40
//        Pdata: return data
//        pLen:  Pdata's length
//  RETURNED£ºSUCCESS - 0
/******************************************************
int WINAPI ISO15693_Get_Block_Security(unsigned short icdev,
                       unsigned char  model,
                       unsigned char  *UID,
                       unsigned char  block,
                       unsigned char  number, 
                                           unsigned char  *Pdata,
                                           unsigned char  *pLen);



/******** FUNCTION£ºDisplay message on MR600 ***********
//  PARAMETERS£º
//        icdev£ºdevice address
//        cDecodeModel: decode mode
//        cDpPosition: when cDecodeModel = 1, the point position, could be 0 to 7
//        cDisplayData: display data
//  return:
//        0: success
//        1: failure
//  usage:
//        cDecodeModel=0: the display data are seven segments data, need not to decode with reader
//        cDecodeModel=1: the display data are 0 to 9 in hex mode, reader will decode the data and display it, it the value is 10 (hex: 0x0A) the display bit will be blank
//        cDisplayData: 8 bytes display data
//        when cDecodeModel = 0, the decode table below:
//        display	code
//        '0'		0x7E
//        '1'		0x30
//        '2'		0x6D
//        '3'		0x79
//        '4'		0x33
//        '5'		0x5B
//        '6'		0x5F
//        '7'		0x70
//        '8'		0x7F
//        '9'		0x7B
/*****************************************************************
int WINAPI rf_display(WORD icdev, unsigned char cDecodeModel, unsigned char cDpPosition,
                      unsigned char * DisplayData);

/******** FUNCTION£ºwrite data to FLASH in MR600 ***********
//  PARAMETERS£º
//        icdev£ºdevice address
//        iBlock: block number, 256 bytes per block, total 2048 blocks, 0x0000 - 0x07FF
//        cStartAddress: wirte start addr. in block, 0 - 255
//        cBytes: bytes to write
//        WriteData: data to write
//  return:
//        0: success
//        1: failure
//  notice:
//        max. 224 bytes per command
//        cStartAddress + cBytes <= 256
/*****************************************************************
int WINAPI rf_flash_write(WORD icdev, unsigned short iBlock, unsigned char cStartAddress,
                          unsigned char cBytes, unsigned char * WriteData);



/******** FUNCTION£ºread data from FLASH in MR600 ***********
//  PARAMETERS£º
//        icdev£ºdevice address
//        iBlock: block number, 256 bytes per block, total 2048 blocks, 0x0000 - 0x07FF
//        cStartAddress: wirte start addr. in block, 0 - 255
//        cBytes: bytes to write
//        pData: data read
//  return:
//        0: success
//        1: failure
//  notice:
//        max. 224 bytes per command
//        cStartAddress + cBytes <= 256
/*****************************************************************
int WINAPI rf_flash_read(WORD icdev, unsigned short iBlock, unsigned char cStartAddress,
                         unsigned char cBytes, unsigned char * pData);


/****** FUNCTION£ºfind a ISO14443 TYPE A card, support 3 level anticollision **
//  PARAMETERS£ºicdev: device address
//        	cModel: request mode 0x52 or 0x26
//        	pLen: returned data length
//       	pUidLength: the UID length
//       	pData: returned data, they are: 2 bytes ATQA + 1 bytes SAK + 4 or 7 or 10 bytes UID
//  Note£ºmode=0x26: REQA, search card that not halted
//        mode=0x52: WUPA, search all card 
/*****************************************************************
int WINAPI rf_search_type_a(WORD icdev, unsigned char cModel, unsigned char *pData, unsigned char *pLen, unsigned char * pUidLength)£»


/****** FUNCTION£ºISO14443-4 TYPE A card reest *******************
//  PARAMETERS£ºicdev: device address
//        	cModel: request mode 0x52 or 0x26
//        	pLen: returned data length
//       	pData: ATS, card reset infomation
/*****************************************************************
int WINAPI rf_iso14443_4_type_a_reset(WORD icdev, unsigned char *pData, unsigned char *pLen);


*/